/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG                        *
*Copyright (C) 2006, Tony Sparks                                                     *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "GUI_Manager.h"
#include "Component.h"

namespace gui
{
    // instance
    GUI_Manager* GUI_Manager::instance = new GUI_Manager;

GUI_Manager::GUI_Manager(void)
{
}

GUI_Manager::~GUI_Manager(void)
{
    type_ComponentList::iterator it = m_components.begin();
    for( ; it != m_components.end(); ++it )
    {
        delete *it;
    }
}

/** Remove a component */
void GUI_Manager::RemoveComponent(gui::Component *c)
{
    c->m_CanRemove = true;
    //type_ComponentList::iterator it = m_components.begin();
    //for( ; it != m_components.end(); ++it )
    //{
    //    if ( *it == c )
    //    {

    //        m_components.erase( it );
    //        delete *it;
    //        return;
    //    }
    //}
}

/** Get a component */
gui::Component* GUI_Manager::GetParentComponent(gui::Component *c) const
{
    type_ComponentList::const_iterator it = m_components.begin();
    for( ; it != m_components.end(); ++it )
    {
        if ( *it == c )
        {
            return *it;
        }
    }
    return NULL;
}

/** Get a component */
gui::Component* GUI_Manager::GetParentComponent(const std::string &name) const
{
    type_ComponentList::const_iterator it = m_components.begin();
    for( ; it != m_components.end(); ++it )
    {
        if ( (*it)->GetName() == name )
        {
            return *it;
        }
    }
    return NULL;
}


/** Update this component */
void GUI_Manager::Update( long dt )
{
    type_ComponentList::iterator it = m_components.begin();
    while( it != m_components.end() )
    {
        if ( (*it)->HasFocus() )
        {
            (*it)->Update( dt );
        }
        // prune
        if ( (*it)->m_CanRemove )
        {
            std::cout << "Destroying: " << (*it)->GetName() << "\n";
            delete (*it);
            it = m_components.erase( it );
        }
        else
        {
            ++it;
        }
    }
}


/** Render the components */
void GUI_Manager::Render( IRender* r )
{   // render from back to front
    type_ComponentList::iterator it = m_components.begin();
    for( ; it != m_components.end(); ++it )
    {
        if ( (*it)->IsVisible() )
            (*it)->Render( r );
    }
}

/** Pump input, feed the input until
    we hit an active component
 */
void GUI_Manager::PumpInput()
{
    // render from back to front
    type_ComponentList::reverse_iterator it = m_components.rbegin();
    for( ; it != m_components.rend(); ++it )
    {
        if ( (*it)->HandleInput() ) return;
    }
}


/** Push to front */
void GUI_Manager::PushToFront(  Component* c )
{
    type_ComponentList::iterator it = m_components.begin();
    for( ; it != m_components.end(); ++it )
    {
        if ( *it == c )
        {
            m_components.erase( it );
            m_components.push_back( c );
            return;
        }
    }
}

void GUI_Manager::PushToFront( const std::string &name )
{
    type_ComponentList::iterator it = m_components.begin();
    for( ; it != m_components.end(); ++it )
    {
        if ( (*it)->GetName() == name )
        {
            Component* c = (*it);
            m_components.erase( it );
            m_components.push_back( c );
            return;
        }
    }
}


/** Handle an event */
bool GUI_Manager::HandleEvent( IEvent* e )
{
    ActivationEvent* act = e->GetData<ActivationEvent>();
    SetStatusOfComponents( act->m_list, act->type );

    return true;
}


/** De/Activate components */
void GUI_Manager::SetStatusOfComponents( std::vector<std::string> &list, int status )
{
    bool active = ( status == ActivationEvent::ACTIVATE );
    std::vector<std::string>::iterator it = list.begin();
    for ( ; it != list.end(); ++it )
    {
        GetParentComponent( (*it) )->SetVisible( active );
    }
}


};
